package com.anytrek.cloudorder.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.anytrek.cloudcommon.utils.ApiResult;
import com.anytrek.cloudcommon.utils.Tools;
import com.anytrek.cloudopenfeign.openfeign.CommodityClient;
import com.anytrek.cloudopenfeign.openfeign.UsersClient;
import com.anytrek.cloudorder.service.OrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.anytrek.cloudcommon.entity.OrdersEntity;
import com.anytrek.cloudcommon.mapper.OrdersMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.spring.annotation.datasource.EnableAutoDataSourceProxy;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.util.List;

/**
* @author Alex2
* @description 针对表【t_orders】的数据库操作Service实现
* @createDate 2025-08-22 10:48:54
*/
@Log4j2
@Service
@RequiredArgsConstructor
@EnableAutoDataSourceProxy
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, OrdersEntity>
    implements OrdersService {

    private static final String TAG = "Alex";

    private final UsersClient usersClient;

    private final CommodityClient commodityClient;

    @Override
    public ApiResult getOrderByUserId(Integer userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<OrdersEntity> list = lambdaQuery().eq(OrdersEntity::getUserId, userId).list();
        PageInfo<OrdersEntity> pageInfo = new PageInfo<>(list);
        return Tools.pageHelperResult(list, pageInfo, TAG);
    }

    @Override
    public ApiResult getOrderById(Integer id) {
        OrdersEntity ordersEntity = lambdaQuery().eq(OrdersEntity::getId, id).one();
        if (ordersEntity == null) {
            return ApiResult.error("获取订单失败");
        }
        return ApiResult.success("获取订单成功", ordersEntity);
    }

    @Override
    public ApiResult payment() {
        return ApiResult.success("支付订单成功");
    }

    @Override
    public ApiResult updateOrderById(Integer id, String name, Integer price, Integer userId) {
        return ApiResult.success("更新订单成功");
    }

    @Override
    public ApiResult deleteOrderById(Integer id) {
        return ApiResult.success("删除订单成功");
    }

    @Override
    @SentinelResource(value = "getUserById")
    public ApiResult getUserById(Integer id) {
        OrdersEntity ordersEntity = lambdaQuery().eq(OrdersEntity::getId, id).one();
        Integer userId = ordersEntity.getUserId();
        return ApiResult.success("获取用户成功", userId);
    }

    /**
     * @ Author: Alex
     * @ Description: 项目实战-分布式事务-插入订单
     */
    @Override
    @GlobalTransactional(name = "order-create-tx", rollbackFor = Exception.class)
    public ApiResult insertOrder(Integer commodityId, Integer count, Integer userId) {
        // 校验用户
        ApiResult userResult  = usersClient.getUserById(userId);
        if(userResult.isError()) {
            log.error("{} : {}", TAG, userResult.getMsg());
            throw new RuntimeException(userResult.getMsg());
        }

        // 获取商品价格
        ApiResult priceResult = commodityClient.getPriceByCommodityId(commodityId);
        if(priceResult.isError()){
            log.error("{} : {}", TAG, priceResult.getMsg());
            throw new RuntimeException(priceResult.getMsg());
        }
        Integer commodityPrice = (Integer) priceResult.getData();

        // 扣减库存
        ApiResult stockResult = commodityClient.deductStock(commodityId, count);
        if (stockResult.isError()) {
            log.error("{} : {}", TAG, stockResult.getMsg());
            throw new RuntimeException(stockResult.getMsg());
        }

        // 扣减余额
        ApiResult balanceResult = usersClient.deductBalance(userId, commodityPrice * count);
        if (balanceResult.isError()) {
            log.error("{} : {}", TAG, balanceResult.getMsg());
            throw new RuntimeException(balanceResult.getMsg());
        }

        // 插入订单
        OrdersEntity ordersEntity = new OrdersEntity(null, userId, commodityId, count, commodityPrice * count);
        boolean save = save(ordersEntity);
        if (!save) {
            log.error("{} : {}", TAG, "插入订单失败");
            throw new RuntimeException("插入订单失败");
        }
        log.info("{} : {}", TAG, "插入订单成功");
        return ApiResult.success("插入订单成功");
    }
}